package network;


import java.io.IOException;
import java.net.*;
import java.util.Scanner;

// 客户端
public class UdpEchoClient {
    private DatagramSocket socket = null;
    private String serverIp =  null;
    private int serverPort = 0;

    public UdpEchoClient(String serverIp ,int serverPort) throws SocketException {
        this.socket = new DatagramSocket();
        // 构造客户端的时候并不需要自己指定端口号，而是让服务器分配
        // 客户端给服务器发送数据 此时源ip就是客户端的ip 源端口就是客户端的端口；目的ip就是服务器的ip
        // 目前客户端和服务器都在同一台主机，现在ip都是127.0.0.1  目的端口是9090  此时源端口是操作系统随机分配的空闲端口（端口号用来标识进程，因此同一ip的同一个端口同时不能被多个线程同时占用）
        // 但是一个进程可以绑定多个端口

        // 特殊情况：也可以说成极端情况： 进程绑定一个端口号后，fork一个子进程，可以实现多个进程绑定一个端口号，但是不同的进程不能绑定同一个端口号。
        //【fork一个子进程】：是一个特殊的系统api java标准库也没有提供fork的封装 所以没法使用 可以忽略这种情况
        this.serverIp = serverIp;
        this.serverPort = serverPort;
    }

    public void start() throws IOException {
        System.out.println("============= 客户端启动！================");
        Scanner scanner = new Scanner(System.in);
        while(true){
            //1 从控制台读取需要发送的数据
            System.out.print(">");
            String request = scanner.next();
            if(request.equals("exit")){
                System.out.println("GOODBYE!");
                break;
            }
            //2.构造成udp请求并发送
            // 构造这个Packet的时候，需要将IP和端口号都传进来，ip地址需要转化为32wei 需要使用InetAddress.getByName来转换
            DatagramPacket requestPacket = new DatagramPacket(request.getBytes(),request.getBytes().length, InetAddress.getByName(serverIp),serverPort);
            //3.发送
            socket.send(requestPacket);
            //4. 读取服务器的响应并且解析
            DatagramPacket responsePacket = new DatagramPacket(new byte[4096],4096);
            socket.receive(responsePacket);
            //5.显示
            String responseStr = new String(responsePacket.getData(),0, responsePacket.getLength());
            System.out.println(responseStr);
        }
    }


    // 当前的客户端和服务器都在通过一台主机上运行，实际上网络存在的意义就是跨主机通信，当前的程序是可以做到跨主机通信的
    // 如果将客户端代码随便给另外的主机 另外的主机能够直接连上服务器呢？其实是不行的（连不上自己的电脑很正常，但是有办法让另外的主机连上别的电脑） ---》云服务器的作用 云服务器有外网ip 任何一个链上网络的设备都可以访问，自己的电脑只能在局域网内部访问
    public static void main(String[] args) throws IOException {
        UdpEchoClient udpEchoClient = new UdpEchoClient("127.0.0.1", 9090);
        udpEchoClient.start();
    }
}
